package com.zx.onlineeducation.service.vod.service.impl;

import com.aliyun.vod.upload.impl.UploadVideoImpl;
import com.aliyun.vod.upload.req.UploadStreamRequest;
import com.aliyun.vod.upload.resp.UploadStreamResponse;
import com.aliyuncs.DefaultAcsClient;
import com.aliyuncs.exceptions.ClientException;
import com.aliyuncs.vod.model.v20170321.*;
import com.google.gson.Gson;
import com.zx.onlineeducation.common.servicebase.exception.OnlineEducationException;
import com.zx.onlineeducation.service.vod.config.VodProperties;
import com.zx.onlineeducation.service.vod.service.VodService;
import com.zx.onlineeducation.service.vod.util.InitObject;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import java.io.InputStream;
import java.util.List;

/**
 * Vod视频点播 服务实现类
 *
 * @author 郑雪
 * @since 2022-01-16
 */
@Service
@Slf4j
public class VodServiceImpl implements VodService {

    /**
     * 第三方VOD视频点播服务接口属性
     */
    @Autowired
    private VodProperties vodProperties;

    /**
     * 上传视频VOD服务器
     *
     * @param multipartFile 要上传的文件
     * @return 返回上传后的云端视频资源ID
     * @author 郑雪
     * @since 2022-01-11
     */
    @Override
    public String uploadVideo(MultipartFile multipartFile) {

        // 获取文件输入流
        InputStream inputStream;
        try {
            inputStream = multipartFile.getInputStream();
        } catch (Exception e) {
            throw new OnlineEducationException(20001, "上传视频失败，请重新上传！");
        }

        // 1.创建流式上传视频的请求对象
        UploadStreamRequest request = new UploadStreamRequest(vodProperties.getAccessKeyId(), vodProperties.getAccessKeySecret(), multipartFile.getOriginalFilename(), multipartFile.getOriginalFilename(), inputStream);
        request.setApiRegionId(vodProperties.getRegionId());    // 设置点播服务接入地域

        // 2.创建上传视频对象
        UploadVideoImpl uploader = new UploadVideoImpl();

        // 3.通过执行流式上传视频获得上传视频的响应对象
        UploadStreamResponse response = uploader.uploadStream(request);
        log.info("-------------视频上传结果----------------");
        log.info("响应对象：{}", new Gson().toJson(response));

        // 4.获取视频ID
        String videoId = response.getVideoId();
        log.info("视频ID：{}", videoId);
        log.info("---------------------------------------");

        // 7.返回视频ID
        return videoId;
    }

    /**
     * 根据视频ID获取视频播放地址
     *
     * @param videoId 视频ID
     * @return 视频播放地址
     * @author 郑雪
     * @since 2022-01-16
     */
    @Override
    public String getVideoPlayUrlById(String videoId) {
        // 1.初始化视频点播客户端
        DefaultAcsClient client = InitObject.initVodClient(vodProperties.getAccessKeyId(), vodProperties.getAccessKeySecret(), vodProperties.getRegionId());

        // 2.创建获取视频播放地址的请求对象
        GetPlayInfoRequest request = new GetPlayInfoRequest();
        request.setVideoId(videoId);    // 设置视频ID

        // 3.通过视频点播客户端发送请求得到获取视频播放地址的响应对象
        GetPlayInfoResponse response;
        try {
            response = client.getAcsResponse(request);
        } catch (ClientException e) {
            throw new OnlineEducationException(20001, "获取视频播放地址失败！");
        }

        // 4.获取视频基本信息（包含视频标题、视频封面、视频时长等属性）
        GetPlayInfoResponse.VideoBase videoBase = response.getVideoBase();
        log.info("视频基本信息：{}", new Gson().toJson(videoBase));

        // 5.获取视频播放信息列表
        List<GetPlayInfoResponse.PlayInfo> playInfoList = response.getPlayInfoList();

        if (playInfoList == null || playInfoList.isEmpty()) {
            throw new OnlineEducationException(20001, "获取视频播放地址失败");
        }

        // 6.获取视频播放信息（包含宽度、高度、编码格式、码率、帧率、播放地址等属性）
        GetPlayInfoResponse.PlayInfo playInfo = playInfoList.get(0);
        log.info("视频播放信息：{}", new Gson().toJson(playInfo));

        // 7.返回视频播放地址
        return playInfo.getPlayURL();
    }

    /**
     * 根据视频ID获取视频播放凭证
     *
     * @param videoId 视频ID
     * @return 视频播放凭证
     * @author 郑雪
     * @since 2022-01-16
     */
    @Override
    public String getVideoPlayAuthById(String videoId) {
        // 1.初始化视频点播客户端
        DefaultAcsClient client = InitObject.initVodClient(vodProperties.getAccessKeyId(), vodProperties.getAccessKeySecret(), vodProperties.getRegionId());

        // 2.创建获取视频播放凭证的请求对象
        GetVideoPlayAuthRequest request = new GetVideoPlayAuthRequest();
        request.setVideoId(videoId);    // 设置视频ID

        // 3.通过视频点播客户端发送请求得到获取视频播放凭证的响应对象
        GetVideoPlayAuthResponse response;
        try {
            response = client.getAcsResponse(request);
        } catch (ClientException e) {
            throw new OnlineEducationException(20001, "获取视频播放凭证失败！");
        }

        // 4.获取视频播放凭证
        String playAuth = response.getPlayAuth();
        log.info("视频播放凭证：{}", new Gson().toJson(playAuth));

        // 5.获取视频Meta信息（包含视频标题、视频封面、视频时长、视频状态等属性）
        GetVideoPlayAuthResponse.VideoMeta videoMeta = response.getVideoMeta();
        log.info("视频Meta信息：{}", new Gson().toJson(videoMeta));

        // 7.返回视频播放凭证
        return playAuth;
    }

    /**
     * 根据视频ID删除VOD服务器中的视频资源
     *
     * @param videoIds 视频Ids字符串，支持传入多个视频ID，多个用逗号分隔
     * @return 成功true，失败false
     * @author 郑雪
     * @since 2022-01-16
     */
    @Override
    public boolean removeVideoByIds(String videoIds)  {
        // 1.初始化视频点播客户端
        DefaultAcsClient client = InitObject.initVodClient(vodProperties.getAccessKeyId(), vodProperties.getAccessKeySecret(), vodProperties.getRegionId());

        // 2.创建删除视频的请求对象
        DeleteVideoRequest request = new DeleteVideoRequest();
        request.setVideoIds(videoIds);    // 支持传入多个视频ID，多个用逗号分隔

        try {
            // 3.通过视频点播客户端发送请求得到删除视频的响应对象
            DeleteVideoResponse response = client.getAcsResponse(request);
            log.info("删除云端视频资源成功，视频Ids：{}，请求ID：{}", videoIds, response.getRequestId());

            // 返回成功
            return true;
        } catch (Exception e) {
            // 返回失败
            return false;
        }
    }

}
